using System.Collections;
using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(CapsuleCollider2D))]
[RequireComponent(typeof(ItemDrop))]
[RequireComponent(typeof(EntityFX))]
[RequireComponent(typeof(EnemyStats))]
public class Enemy : Entity
{
    public LayerMask PlayerLayer { get; private set; }
    public EnemyStateMachine StateMachine { get; private set; }
    public Player Player { get; protected set; }
    [Header("Move info")]
    public float moveSpeed = 1.5f;
    public float idleTime = 2;
    public float battleTime = 7;
    private float defaultMoveSpeed;
    [Header("Attack info")]
    public float agroDistance = 2;
    public float attackDistance = 2;
    public float attackCooldown = 2;
    public float minAttackCooldown = 1.5f;
    public float maxAttackCooldown = 3;
    [HideInInspector] public float lastTimeAttacked;
    [Header("Stunned info")]
    public float stunnedDuration = 2f;
    public Vector2 stunnedDirection = new(7, 7);
    protected bool canBeStunned = false;
    public GameObject CounterImage { get; private set; }
    public string LastAnimBoolName { get; private set; }

    protected override void Awake()
    {
        base.Awake();
        StateMachine = new();
        PlayerLayer = LayerMask.GetMask("Player");
        defaultMoveSpeed = moveSpeed;
        CounterImage = transform.Find("CounterImage").gameObject;
        CounterImage.SetActive(false);
    }

    private void Update()
    {
        Player = IsPlayerDetected();
        StateMachine.CurrentState.Update();
    }

    public virtual void SpeicalAttackTrigger() { }

    public virtual void AssignLastAnimName(string animBoolName) => LastAnimBoolName = animBoolName;

    public override void SlowEntityBy(float slowPercentage, float slowDuration)
    {
        base.SlowEntityBy(slowPercentage, slowDuration);
        moveSpeed *= 1 - slowPercentage;
        Anim.speed *= 1 - slowPercentage;
        Invoke(nameof(ReturnDefaultSpeed), slowDuration);
    }

    protected override void ReturnDefaultSpeed()
    {
        base.ReturnDefaultSpeed();
        moveSpeed = defaultMoveSpeed;
    }

    public virtual void FreezeTime(bool timeFrozen)
    {
        if (timeFrozen)
        {
            moveSpeed = 0;
            Anim.speed = 0;
        }
        else
        {
            moveSpeed = defaultMoveSpeed;
            Anim.speed = 1;
        }
    }

    public virtual void FreezeTimeFor(float duration) => _ = StartCoroutine(FreezeTimerFor(duration));

    protected virtual IEnumerator FreezeTimerFor(float duration)
    {
        FreezeTime(true);
        yield return new WaitForSeconds(duration);
        FreezeTime(false);
    }

    // public virtual RaycastHit2D IsPlayerDetected()
    // {
    //     RaycastHit2D hit = Physics2D.Raycast(transform.position, transform.right, 15f, playerLayer);
    //     return hit;
    // }

    public virtual Player IsPlayerDetected()
    {
        Collider2D coll = Physics2D.OverlapCircle(transform.position, 20f, PlayerLayer);
        if (!coll) return null;
        if (coll.TryGetComponent(out Player player))
            return player;
        else
            return null;
    }

    public virtual void OpenCounterAttackWindow()
    {
        canBeStunned = true;
        CounterImage.SetActive(true);
    }

    public virtual void CloseCounterAttackWindow()
    {
        canBeStunned = false;
        CounterImage.SetActive(false);
    }

    public virtual bool CanBeStunned()
    {
        if (!canBeStunned) return false;
        CloseCounterAttackWindow();
        return true;
    }

#if UNITY_EDITOR
    protected override void OnDrawGizmos()
    {
        base.OnDrawGizmos();
        Gizmos.color = Color.blue;
        Gizmos.DrawLine(transform.position, new Vector2(transform.position.x + 15 * FacingDirection, transform.position.y));
        Gizmos.color = Color.green;
        Gizmos.DrawLine(transform.position, new Vector2(transform.position.x + attackDistance * FacingDirection, transform.position.y));
    }

    public virtual void SelfDestory()
    {
        Destroy(gameObject);
    }
#endif
}